﻿/*
 * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
 */

#ifndef USB_DFU_H
#define USB_DFU_H
#include <cstdint>

#ifdef _MSC_VER
# pragma pack(push)
# pragma pack(1)
#endif /* _MSC_VER */
namespace UsbDfu {
struct UsbDfuFuncDescriptor {
    uint8_t		bLength;
    uint8_t		bDescriptorType;
    uint8_t		bmAttributes;
#define USB_DFU_CAN_DOWNLOAD	(1 << 0)
#define USB_DFU_CAN_UPLOAD	(1 << 1)
#define USB_DFU_MANIFEST_TOL	(1 << 2)
    uint16_t		wDetachTimeOut;
    uint16_t		wTransferSize;
    uint16_t		bcdDFUVersion;
#ifdef _MSC_VER
};
# pragma pack(pop)
#elif defined __GNUC__
# if defined __MINGW32__
} __attribute__ ((__packed__, __gcc_struct__));
# else
} __attribute__ ((__packed__));
# endif
#else
 #warning "No way to pack struct on this compiler? This will break!"
#endif /* _MSC_VER */

#define USB_DT_DFU_SIZE			9

#define USB_TYPE_DFU		(LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE)

#define USB_REQ_DFU_DETACH	0x00
#define USB_REQ_DFU_DNLOAD	0x01
#define USB_REQ_DFU_UPLOAD	0x02
#define USB_REQ_DFU_GETSTATUS	0x03
#define USB_REQ_DFU_CLRSTATUS	0x04
#define USB_REQ_DFU_GETSTATE	0x05
#define USB_REQ_DFU_ABORT	0x06

enum class DfuState {
    DFU_STATE_APP_IDLE		= 0,
    DFU_STATE_APP_DETACH		= 1,
    DFU_STATE_DFU_IDLE		= 2,
    DFU_STATE_DFU_DNLOAD_SYNC	= 3,
    DFU_STATE_DFU_DNBUSY		= 4,
    DFU_STATE_DFU_DNLOAD_IDLE	= 5,
    DFU_STATE_DFU_MANIFEST_SYNC	= 6,
    DFU_STATE_DFU_MANIFEST		= 7,
    DFU_STATE_DFU_MANIFEST_WAIT_RST	= 8,
    DFU_STATE_DFU_UPLOAD_IDLE	= 9,
    DFU_STATE_DFU_ERROR		= 10
};
}

#endif /* USB_DFU_H */
